package com.bitmonlab.osiris.core.validations.aspect; import java.lang.reflect.Method; import javax.inject.Named; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.reflect.MethodSignature; import com.bitmonlab.osiris.core.validations.annotations.ValidationRequired; import com.bitmonlab.osiris.core.validations.aspect.contractViolationProcessor.api.MethodContractViolationProcessor; import com.bitmonlab.osiris.core.validations.validador.api.MethodInvocationValidator; /** * Aspect use to validate the invocation of the contract of the method. */ @Aspect @Named public class MethodInvocationValidationAspect { /** * Method that execute around a method in order to execute the validations. * * @param joinPoint the joint point that execute. * @return Object return of the execution. * @throws Throwable exception when a problem occurs in the invocation of the contract. */ @Around("execution(@com.bitmonlab.osiris.core.commons.validations.annotations.ValidationRequired public * *.*(..))") public Object validateMethodContract(ProceedingJoinPoint joinPoint) throws Throwable { validateMethodParameters(joinPoint); Object result = executeMethod(joinPoint); validateReturnValue(joinPoint,result); return result; } /** * Method that execute the method. * @param joinPoint the joint point. * @return the result of the method execution. * @throws Throwable exceptions generate by the method. */ private Object executeMethod(ProceedingJoinPoint joinPoint) throws Throwable { return joinPoint.proceed(); } /** * Method that validate if the return value. * @param joinPoint the joint point of the method. * @param returnValue the result value. * @throws Exception the exception throwing when a problem occurs. */ private void validateReturnValue(ProceedingJoinPoint joinPoint,Object returnValue) throws Exception { Method method = retreiveCallMethod(joinPoint); MethodContractViolationProcessor violationProcessor = retrieveViotationProcessor(method); MethodInvocationValidator validator = retrieveMethodValidator(method); violationProcessor.processMethodReturnValueValidation( validator.isValidReturnValue(joinPoint.getTarget(), method, returnValue)); } /** * Method that retrieve the calling method. * @param joinPoint the joint point. * @return the method called method. */ private Method retreiveCallMethod(ProceedingJoinPoint joinPoint) { MethodSignature signature = (MethodSignature) joinPoint.getSignature(); return signature.getMethod(); } /** * Method that validate the input parameters of a method. * @param joinPoint the method joint point. * @throws Exception the exception throwing when a problem occurs. */ private void validateMethodParameters(ProceedingJoinPoint joinPoint) throws Exception { Method method = retreiveCallMethod(joinPoint); MethodContractViolationProcessor violationProcessor = retrieveViotationProcessor(method); MethodInvocationValidator validator = retrieveMethodValidator(method); violationProcessor.processMethodParameterValidation( validator.areValidInvocationParameters(joinPoint.getTarget(),method, joinPoint.getArgs())); } /** * Method that return the processor defined in the method annotation. * @param method the annotated method. * @return the constraints violation processor. * @throws InstantiationException exception if it's not possible instantiate the processor. * @throws IllegalAccessException if it's not possible access to processor. */ private MethodContractViolationProcessor retrieveViotationProcessor(Method method) throws InstantiationException, IllegalAccessException { ValidationRequired annotation = method.getAnnotation(ValidationRequired.class); Class<? extends MethodContractViolationProcessor> processorClass = annotation.processor(); return processorClass.newInstance(); } /** * Method that retrieve the validator indicates in the annotation. * @param method the method that is execute. * @return The method validator. * @throws InstantiationException the exception in the instantiation. * @throws IllegalAccessException the exception is has been an illegal access. */ MethodInvocationValidator retrieveMethodValidator(Method method) throws InstantiationException, IllegalAccessException { ValidationRequired annotation = method.getAnnotation(ValidationRequired.class); Class<? extends MethodInvocationValidator> validatorClass = annotation.validator(); return validatorClass.newInstance(); } }